package com.tarena.demo.luban.all.main.service.impl;

import cn.tedu.luban.demo.cart.api.CartApi;
import cn.tedu.luban.demo.stock.api.StockApi;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.Sph;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.tarena.demo.luban.all.main.mapper.OrderMapper;
import com.tarena.demo.luban.all.main.service.OrderService;
import com.tarena.demo.luban.protocol.cart.param.CartDeleteParam;
import com.tarena.demo.luban.protocol.order.dos.OrderDO;
import com.tarena.demo.luban.protocol.order.param.OrderAddParam;
import com.tarena.demo.luban.protocol.stock.param.StockReduceCountParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.rpc.RpcContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.Future;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired(required = false)
    private CartApi cartApi;
    @Autowired(required = false)
    private StockApi stockApi;
    /*@Autowired
    private CartService cartService;*/
    /*@Autowired
    private StockService stockService;*/
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public void addOrder(OrderAddParam param) {
        String orderSn = param.getOrderSn();
        //select count(id) from order_tbl where order_sn=#{orderSn}
        Integer total=orderMapper.countOrderByOrderSn(orderSn);
        if (total>0){
            return;
        }
        // 减库存
        StockReduceCountParam stockReduceCountParam=new StockReduceCountParam();
        stockReduceCountParam.setReduceCount(param.getCount());
        stockReduceCountParam.setProductCode(param.getProductCode());
        stockReduceCountParam.setOrderSn(param.getOrderSn());
        stockApi.reduceCount(stockReduceCountParam);
        //stockService.reduceCommodityCount(stockReduceCountParam);
        //增订单
        OrderDO orderDO=new OrderDO();
        BeanUtils.copyProperties(param,orderDO);
        orderMapper.insertOrder(orderDO);
        //删除购物车 代码片段定义成资源
        Entry entry=null;
        try{
            entry= SphU.entry("cartDelete");
            CartDeleteParam cartDeleteParam=new CartDeleteParam();
            cartDeleteParam.setUserId(param.getUserId());
            cartDeleteParam.setProductCode(param.getProductCode());
            System.out.println("注入cartApi:"+cartApi.getClass().getName());
            //同步调用 能够拿到返回值true
            //异步调用 无法直接拿到返回值,必须通过dubbo异步处理 使用回调获取返回值
            Boolean cartDelete = cartApi.cartDelete(cartDeleteParam);
            //结果是null
            log.info("获取到返回值cartDelete结果:{}",cartDelete);
            RpcContext context=RpcContext.getContext();
            //拿到异步线程 future对象
            Future<Object> future = context.getFuture();
            //future包含的就是回调方法,什么时候 provider执行完,回调方法什么时候拿到反馈结果
            //cartDelete返回值 boolean true
            Object result = future.get();
            log.info("拿到真正的返回值:{}",result);
            log.info("调用删除购物车后续代码");
        }catch (BlockException e){
            //处理sentinel 熔断降级逻辑
            //详细记录日志 谁 什么时间 哪张订单 删除哪个购物车 失败
        }catch (Exception e){
            //系统其他异常
            // 日志记录 监控接口
        }finally {
            if (entry!=null)entry.exit();
        }

    }
}
